package com.crois.barrier.metrics.prometheus.register;

import com.crois.barrier.metrics.api.MetricsRegister;
import io.prometheus.client.Counter;
import io.prometheus.client.Gauge;
import io.prometheus.client.Histogram;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Hou Ze Yu
 * @description Prometheus metrics register.
 * @date 2021/4/22
 */
public class PrometheusMetricsRegister implements MetricsRegister {

    private static final Map<String, Counter> COUNTER_MAP = new ConcurrentHashMap<>();

    private static final Map<String, Gauge> GAUGE_MAP = new ConcurrentHashMap<>();

    private static final Map<String, Histogram> HISTOGRAM_MAP = new ConcurrentHashMap<>();


    private static class PrometheusMetricsRegisterHolder {
         private static final PrometheusMetricsRegister INSTANCE = new PrometheusMetricsRegister();
    }
    /**
     * get prometheus Metrics Register Instance
     * @return
     */
    public static PrometheusMetricsRegister getInstance() {
        return PrometheusMetricsRegisterHolder.INSTANCE;
    }

    @Override
    public void registerGauge(String name, String[] labelNames, String document) {
        if (!GAUGE_MAP.containsKey(name)){
           Gauge.Builder builder = Gauge.build().name(name).help(document);
           if (null!=labelNames) {
               builder.labelNames(labelNames);
           }
           GAUGE_MAP.put(name,builder.register());
        }
    }

    @Override
    public void registerCounter(String name, String[] labelNames, String document) {
        if (!COUNTER_MAP.containsKey(name)){
            Counter.Builder builder = Counter.build().name(name).help(document);
            if (null!=labelNames) {
                builder.labelNames(labelNames);
            }
            COUNTER_MAP.put(name,builder.register());
        }
    }

    @Override
    public void registerHistogram(String name, String[] labelNames, String document) {
        if (!HISTOGRAM_MAP.containsKey(name)){
            Histogram.Builder builder = Histogram.build().name(name).help(document);
            if (null!=labelNames) {
                builder.labelNames(labelNames);
            }
            HISTOGRAM_MAP.put(name,builder.register());
        }
    }

    @Override
    public void counterIncrement(String name, String[] labelValues) {
        Counter counter = COUNTER_MAP.get(name);
        if (null!=labelValues) {
            counter.labels(labelValues).inc();
        }else {
            counter.inc();
        }

    }

    @Override
    public void counterIncrement(String name, String[] labelValues, long count) {
        Counter counter = COUNTER_MAP.get(name);
        if (null!=labelValues) {
            counter.labels(labelValues).inc(count);
        }else {
            counter.inc(count);
        }

    }

    @Override
    public void gaugeIncrement(String name, String[] labelValues) {
       Gauge gauge = GAUGE_MAP.get(name);
       if (null!=labelValues){
           gauge.labels(labelValues).inc();
       }else {
           gauge.inc();
       }
    }

    @Override
    public void gaugeDecrement(String name, String[] labelValues) {
        Gauge gauge = GAUGE_MAP.get(name);
        if (null!=labelValues){
            gauge.labels(labelValues).dec();
        }else {
            gauge.dec();
        }
    }

    @Override
    public void recordTime(String name, String[] labelValues, long duration) {
          Histogram histogram = HISTOGRAM_MAP.get(name);
          if (null!=labelValues){
                histogram.labels(labelValues).observe(duration);
          }else {
              histogram.observe(duration);
          }
    }
}
